<template>
	<el-cascader
		ref="cascader"
		:filterable="true"
		:placeholder="placeholder"
		:clearable="clearable"
		:collapse-tags="true"
		:show-all-levels="false"
		:disabled="disabled"
		:options="options"
		:props="props"
		:value="cascaderValue"
		@change="change"
	/>
</template>

<script>
	import bdApi from "@rc/apis/bd/index.mjs";

	export default {
		props: {
			/**
			 * 当前的默认的选中值
			 * 1.支持v-model
			 * 2.默认单选，支持传入两种风格  1.[子projectId] 2.[父projectId,子projectId]，注：修改后传出的是第二种格式
			 * 3.多选(propsOptions.multiple = true)  1. [子projectId,子projectId,...]  2. [[父projectId,子projectId], [父projectId,子projectId]...]，注：修改后传出的是第二种格式
			 */
			value: {
				type: Array,
				default: () => []
			},
			// 是否禁用
			disabled: {
				type: Boolean,
				default: false
			},
			// 是否需要“全部项目”
			hasAllProject: {
				type: Boolean,
				default: false
			},
			showDisabledProject: {
				type: Boolean,
				default: false
			},
			// 是否只显示用户下的项目
			isUserProject: {
				type: Boolean,
				default: false
			},
			// 	菜单code,isUserProject为true时必传
			menuCode: {
				type: String,
				default: ""
			},
			// cascader组件的props参数，会与组件配置的进行合并 https://element.eleme.cn/#/zh-CN/component/cascader
			propsOptions: {
				type: Object,
				default: () => {}
			},
            placeholder:{
                type: String,
				default: "请选择项目"
            },
            //是否可以清除
            clearable:{
                type: Boolean,
				default: false
            }

		},
		data() {
			return {
				options: [], // 树状列表
				flatOptions: [] // 扁平化的列表
			};
		},
		computed: {
			// 级联框基础配置
			props() {
				return {
					multiple: false,
					value: "projectId",
					label: "projectName",
					disabled: "forbidden", //防止接口数据返回的disabled影响可选
					...this.propsOptions
				};
			},
			//经过处理的，符合cascader组件格式需求标准的value
			cascaderValue() {
				let result = [];
				if (this.props.multiple) {
					// 多选类型
					result = this.value.map((i) => {
						if (Array.isArray(i)) {
							// 父级子级全有的多选[[],[]]
							return i;
						} else {
							// 只有子级的多选[子id1,子id2]
							const findItem = this.flatOptions.find((i2) => i2.projectId === i);
							return findItem ? findItem.ids : [];
						}
					});
					result = result.filter((i) => i); // 过滤掉为null的未匹配上的id
				} else {
					// 单选类型
					const childrenId = this.value[this.value.length - 1];
					const findItem = this.flatOptions.find((i) => i.projectId === childrenId);
					result = findItem ? findItem.ids : [];
				}
				return result;
			}
		},
		methods: {
			change(data) {
				if (this.props.multiple && data.some((i) => i[i.length - 1] === "0000")) {
					// 如果是多选，并且选中的有“全部项目”选项
					if (this.value.some((i) => i === "0000" || i[i.length - 1] === "0000")) {
						// 之前就选了全部项目，说明是选了其他项目，把全部项目取消勾选
						data = data.filter((i) => i[i.length - 1] !== "0000");
					} else {
						// 之前没选全部项目，说明是选了全部项目，把其他项目取消勾选
						data = ["0000"];
					}
				}
				this.$emit("input", data);
				this.$emit("change", data);
				this.$emit("change-watch", {
					newData: data,
					oldData: this.value
				});
			},
			api_getCheckedNodes() {
				return this.$refs.cascader.getCheckedNodes();
			}
		},
		created() {
			// 初始化内容数据
			let apiName = "queryProjectTree";
			let params = {
				projectAvlstatus: this.showDisabledProject ? "" : "Y"
			};
			if (this.isUserProject) {
				apiName = "queryProjectTreeByUser";
				params.addUnknown = "N";
				params.menuCode = this.menuCode;
			}

			bdApi[apiName]({
				data: params,
				success: ({ data }) => {
					this.options = data || [];
					if (this.hasAllProject) {
						this.options.unshift({
							projectId: "0000",
							projectName: "全部项目"
						});
					}
					// 扁平化的递归函数
					const flatFun = (arr, item, ids) => {
						arr.push({
							projectId: item.projectId,
							projectName: item.projectName,
							ids: [...ids, item.projectId] // 父子id集合
						});
						if (item.children && item.children.length) {
							item.children.forEach((item2) => {
								flatFun(arr, item2, [...ids, item.projectId]);
							});
						}
					};
					this.options.forEach((item2) => {
						flatFun(this.flatOptions, item2, []);
					});

					const treeList = JSON.parse(JSON.stringify(data));
					const flatList = JSON.parse(JSON.stringify(this.flatOptions));

					this.$emit("ready", treeList, flatList);
				}
			});
		}
	};
</script>

<style scoped lang="less">
	/deep/ .el-cascader__tags .el-tag {
		height: 23px;
        line-height: 23px;

		.el-icon-close {
			top: 1px;
		}
	}
</style>
